home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Amiga
/
World of Amiga.iso
/
archive
/
assembly
/
lsd-lo.s.lha
/
MultiDiskTrackLoader.Src
< prev
next >
Wrap
Text File
|
1980-01-18
|
12KB
|
599 lines
* EXAMPLE OF USE!
move.w #$4000,$dff09a ;Disable Irqs....
jsr INIT_DISK
go moveq #1,d5 ;Load from disk named '1'
move.l #$10000,d6 ;Bytes to load
move.w #880,d7 ;Start block
move.l #loadspace,a6 ;Address of load
jsr BLOCK_LOAD
tst.w d7 ;check for failure
beq.s end
move.w #$7fff,d0 ;red screen = error
erlp move.w #$f00,$dff180
dbf d0,erlp
end jsr MOTOR_OFF
move.w #$c000,$dff09a
rts
loadspace dcb.l $8000,$00
*****************************************************************************
* System Independant Multi-Disk Block Loader V1.1 - 26/4/94 *
*-----------------------------------------------------------------*
* By PHIL RUSTON AKA:PHIL!94/LSD *
* You MUST call "INIT_DISK" before loading for the 1st ever time.
* To LOAD A FILE Set:-
* A6 - Destination Address.
* D5 - Disk / Drive Number to load from. (see below).
* D6 - Bytes to load.
* D7 - Starting Block.
* Then call: "BLOCK_LOAD" - All registers preserved except D7
* D7 returns as 00 is load OK. Else one of the following errors:
* 01 = No speed signal from motor (disk ejected whilst loading)
* 02 = No DMA transfer time out (no sync / '' '' )
* 03 = Disk removed from drive (whilst loading)
* 04 = Can't find that disk block (disk corrupt)
* 05 = Wrong track marker ID ('')
* 06 = Checksum error on disk block ('')
* 07 = Block number req'd too big (you've (in)directly asked for >$6df)
* 08 = Disk requester (Disk specifified in D5 isnt inserted)
* 09 = No disk in that drive (Direct drive access failed)
* 0A = That drive is not connected ('' '')
* When setting D5, if you want to look for a 'named' disk (see docs on
* naming disks) then just set the Longword as $0-$7f as normal in D5.
* If you want to directly access a DRIVE (df0-df3) set the drive number
* to access in D5 and SET the HIGH word to $FFFF. See docs for more info.
* Call "MOTOR_OFF" when finished loading for a while!!
*******************************************************************************
section loadcode,code
**************
* Initialize *
**************
INIT_DISK movem.l a0-a6/d0-d7,-(a7)
move.l #$dff000,a0
move.l #$bfd000,a1
move.l #Variables,a2
clr.l attempts(a2)
clr.l tracksides(a2)
clr.l track_in(a2)
moveq #-1,d7
move.l d7,disks_in(a2)
move.b d7,track_in(a2)
bsr motor_off
bset #3,drives_avail(a2) ;df0: assumed always available
moveq #4,d1
ID_drives move.b #$7f,$100(a1) ;what externals are connected?
bclr d1,$100(a1)
move.w #100,d7
bsr cia_wait
move.b #$ff,$100(a1)
bclr d1,$100(a1)
moveq #$1f,d7
moveq #0,d0
df1idloop lsl.l #1,d0
bclr d1,$100(a1)
btst #5,$1001(a1)
beq.s nxtbit
ori.w #1,d0
nxtbit bset d1,$100(a1)
dbf d7,df1idloop
not.l d0
cmpi.l #-1,d0
bne.s no_drive
bset d1,drives_avail(a2)
no_drive addq.w #1,d1
cmpi.w #7,d1
bne.s ID_drives
bsr motor_off
moveq #0,d0 ;now identify any disks present.
moveq #3,d1
id_dsk_lp btst d1,drives_avail(a2)
beq.s no_drv
move.b d0,use_drive(a2)
move.b #$ff,$100(a1)
bclr d1,$100(a1)
bsr stepin
bsr initialize_drive
btst #2,$1001(a1)
beq.s no_drv
move.b #1,start_motor(a2)
bsr identify_disk
no_drv bsr motor_off
addq.w #1,d1
addq.w #1,d0
cmpi.w #4,d0
bne.s id_dsk_lp
movem.l (a7)+,a0-a6/d0-d7
rts
******************
* Construct file *
******************
BLOCK_LOAD
movem.l d0-d6/a0-a6,-(a7)
move.l #$dff000,a0
move.l #$bfd000,a1
move.l #Variables,a2
clr.b error(a2)
clr.b start_motor(a2)
move.l d7,d4
subq.l #1,d6
tst.l d5 ;Disk or Drive access?
bpl.s find_disk
*****************************************************************************
moveq #3,d7 ;Direct drive access but is that
add.w d5,d7 ;drive attatched?
btst d7,drives_avail(a2)
bne.s drive_ok
move.b #$a,error(a2) ;Drive not connected - error $a
bra load_done
drive_ok
cmp.b use_drive(a2),d5 ;same drive as before?
beq loader
bsr motor_off
move.b d5,use_drive(a2)
moveq #3,d0
add.w d5,d0
bclr d0,$100(a1)
move.b #1,start_motor(a2)
bsr wait1msec
btst #2,$1001(a1)
bne.s disk_now
bsr stepcheck
btst #2,$1001(a1)
bne.s disk_now2
move.b #$9,error(a2)
bra load_done
disk_now2 bsr initialize_drive
bsr identify_disk
disk_now bra loader
*****************************************************************************
find_disk moveq #0,d0 ;Name disk access - is the required
fdisk_lp cmp.b disks_in(a2,d0.w),d5 ;disk already in a drive?
beq found_disk
addq.w #1,d0
cmpi.w #4,d0
bne.s fdisk_lp
disk_gone bsr motor_off ;no drive contains req'd disk
moveq #0,d0 ;so switch 'em off and see if
moveq #3,d1 ;any drive has had a disk replaced.
fdisk_lp2 btst d1,drives_avail(a2)
beq.s dsk_n_rem
move.b #$ff,$100(a1)
bclr d1,$100(a1)
bsr wait1msec
btst #2,$1001(a1) ;disk replaced / ejected?
bne.s dsk_n_rem
move.b d0,use_drive(a2)
bsr stepcheck
btst #2,$1001(a1)
beq.s dsk_n_rem
move.b #1,start_motor(a2)
bsr initialize_drive
bsr identify_disk ;here's a new disk to identify
cmp.b disks_in(a2,d0.w),d5
beq.s loader
bsr motor_off
dsk_n_rem addq.w #1,d1
addq.w #1,d0
cmpi.w #4,d0
bne.s fdisk_lp2
bsr motor_off
move.b #$08,error(a2) ;disk request - error 8.
bra load_done
found_disk
cmp.b use_drive(a2),d0 ;is this a load from the same
beq loader ;drive as the last load?
bsr motor_off
move.b d0,use_drive(a2)
bclr d1,$100(a1)
move.b #1,start_motor(a2)
bsr wait1msec
same_drv btst #2,$1001(a1) ;this drive had the required disk
bne loader ;but has it been ejected?
move.b #$ff,disks_in(a2,d0.w)
bra disk_gone ;yep - so look else where
Loader move.l d4,d0
Nxt_block bsr get_block
tst.b error(a2)
bne.s Load_done
tst.l d6 ;Byte countdown ended?
bmi.s load_done
addq.w #1,d0
bra.s Nxt_block
load_done move.b #$ff,track_in(a2)
tst.b error(a2)
beq.s no_error
bsr motor_off
move.w #1000,d7
bsr cia_wait
no_error moveq #0,d7
move.b error(a2),d7
movem.l (a7)+,d0-d6/a0-a6
rts
*************
* Shut down *
*************
MOTOR_OFF movem.l a1/a2/d7,-(a7)
move.l #$bfd000,a1
move.l #Variables,a2
move.b #$ff,$100(a1)
move.b #$87,$100(a1)
bsr wait1msec
move.b #$ff,$100(a1)
move.b #$ff,use_drive(a2)
moveq #100,d7
bsr cia_wait
movem.l (a7)+,a1/a2/d7
rts
*****************************************************************************
*************
* Get Block *
*************
* D0 will equal block number required ($0 - $6df)
Get_block cmp.w #$6df,d0 ;check block is range
bls.s blockinrange
move.b #$7,error(a2)
bra No_reload
Blockinrange
move.w #$0503,attempts(a2)
move.l d0,d1
divu #11,d1 ;what track/side is that on?
cmp.b track_in(a2),d1
beq.s Trksde_in ;no need to load!
Reload bsr Fetch_trackside ;loads MFM track required
tst.b error(a2)
bne No_reload
Trksde_in clr.b error(a2) ;find a sector
swap d1 ;get sector number lo.
move.l #MFMbuffer,a3
lea $31fe(a3),a5
find_sync move.w #$4489,d7
fs_loop cmp.w (a3)+,d7
beq.s found_sync
cmp.l a5,a3
bls.s fs_loop
move.b #4,error(a2) ;couldnt find that sector-error 4
bra MFM_error
found_sync
cmp.w (a3),d7 ;2 syncs?
beq.s syncstart
subq.w #2,a3
syncstart lea $2a(a3),a4 ;Check header checksum.
bsr decode_lw
move.l $2(a3),d3
move.l $6(a3),d4
andi.l #$55555555,d3
andi.l #$55555555,d4
eor.l d4,d3
cmp.l d3,d5
bne.s Not_sector
lea $2(a3),a4 ;Track mark = Head position?
bsr decode_lw
move.l d5,d4
swap d4
moveq #0,d7
move.b use_drive(a2),d7
cmp.b tracksides(a2,d7.w),d4
beq.s Track_mark_ok
move.b #5,error(a2) ;wrong track mark - error 5
bra MFM_error
Track_mark_ok
lsr.w #8,d5 ;Is this the sector required?
cmp.b d5,d1
beq.s Found_block
Not_sector
add.w #$430,a3 ;loop until find correct sector
bra.s find_sync
Found_Block
moveq #0,d2 ;Transfer converted MFM to dest.
move.l #$55555555,d7
lea $3a(a3),a4
lea $23a(a3),a5
move.l d6,d1 ;back up pointers in case of error.
move.l a6,a3
moveq #$7f,d3
Conv_lw move.l (a4)+,d5
move.l (a5)+,d4
and.l d7,d5
and.l d7,d4
eor.l d5,d2 ;update checksum
eor.l d4,d2
add.l d5,d5
or.l d4,d5
subq.l #4,d6
bmi.s lst_bytes
move.l d5,(a6)+
nxt_lw dbf d3,Conv_lw
bra.s blk_done
Lst_bytes move.w d6,d4
addq.w #4,d4 ;last bytes
bmi.s nxt_lw
Lb_loop rol.l #8,d5
move.b d5,(a6)+
dbf d4,Lb_loop
bra.s nxt_lw
blk_done sub.w #$208,a4 ;get data checksum
bsr decode_lw
cmp.l d5,d2
beq.s no_reload
move.b #6,error(a2) ;checksum error - error 6
move.l a3,a6 ;restore pointers
move.l d1,d6
MFM_error move.l d0,d1
divu #11,d1
subq.b #1,attempts(a2)
bne Reload
bsr initialize_Drive ;reset heads
move.b #5,attempts(a2)
subq.b #1,attempts+1(a2)
bne Reload
No_reload rts
*****************************************************************************
* MFM Track loader!
* D1 will equal trackside 0 - 159
Fetch_trackside
clr.b error(a2)
tst.b start_motor(a2) ;motor on already?
beq.s motor_ok
clr.b start_motor(a2)
move.b #$7f,$100(a1)
moveq #3,d7
add.b use_drive(a2),d7
bclr d7,$100(a1)
move.w #200,d2 ;wait for correct motor speed.
wdskrdy moveq #10,d7
bsr cia_wait
btst #5,$1001(a1)
dbeq d2,wdskrdy
tst.w d2
bpl.s motor_ok
move.b #1,error(a2) ;no speed signal - error 1
btst #2,$1001(a1)
bne.s disk_ok
move.b #3,error(a2) ;disk removed - error 3
disk_ok bra trackload_end
motor_ok move.w d1,d3
lsr.b #1,d3 ;select disk side to load from.
bcc.s head1
bclr #2,$100(a1)
bra.s checkhead
head1 bset #2,$100(a1)
checkhead moveq #0,d7
move.b use_drive(a2),d7
move.b tracksides(a2,d7.w),d2 ;ensure head is over correct
lsr.b #1,d2 ;track
cmp.b d2,d3
beq.s headok
bls.s seekout
bsr stepin
bra.s checkhead
seekout bsr stepout
bra.s checkhead
headok moveq #0,d7
move.b use_drive(a2),d7
move.b d1,tracksides(a2,d7.w)
move.w #$2,$9c(a0) ;clear disk block irq
moveq #18,d7 ;settle wait.
bsr cia_wait
move.l #mfmbuffer,$20(a0)
move.w #$4000,$24(a0)
move.w #$8010,$96(a0) ;enable dma
move.w #$6800,$9e(a0)
move.w #$9500,$9e(a0)
move.w #$4489,$7e(a0) ;sync
move.w #$9900,$24(a0)
move.w #$9900,$24(a0)
move.w #200,d2
waitdirq moveq #10,d7
bsr cia_wait
btst #1,$1f(a0)
dbne d2,waitdirq
tst.w d2
bpl.s read_ok
move.b #2,error(a2) ;No DMA finish-Time Out-error 2
read_ok move.b d1,track_in(a2)
move.w #$4000,$24(a0)
move.w #$10,$96(a0) ;disable dma
Trackload_end
rts
*******************************************************************************
decode_lw move.l #$55555555,d7 ;decode two consec mfm longwords
move.l (a4),d5 ;into d5
move.l $4(a4),d4
and.l d7,d5
and.l d7,d4
add.l d5,d5
or.l d4,d5
rts
stepout moveq #0,d7
move.b use_drive(a2),d7
subq.b #2,tracksides(a2,d7.w)
bset #1,$100(a1)
bra.s step
stepin moveq #0,d7
move.b use_drive(a2),d7
addq.b #2,tracksides(a2,d7.w)
bclr #1,$100(a1)
step bsr.s shortwait
bclr #0,$100(a1)
bsr.s shortwait
bset #0,$100(a1)
moveq #4,d7
bsr cia_wait
rts
shortwait nop
nop
nop
nop
rts
initialize_drive
btst #$4,$1001(a1)
beq.s gottrack0
bsr.s stepout
bra.s initialize_drive
gottrack0 moveq #0,d7
move.b use_drive(a2),d7
clr.b tracksides(a2,d7.w)
move.w #20,d7
bsr cia_wait
rts
Identify_disk
movem.l a6/d0-d1/d4-d7,-(a7)
move.l #ID_buffer,a6
moveq #$c,d6
moveq #$0,d0
bsr get_block
moveq #0,d6
move.b use_drive(a2),d6
tst.b error(a2)
bne.s not_sys
move.w ID_buffer+8,d7
cmpi.w #"PR",d7
beq.s sys_disk
not_sys moveq #-1,d7
bra.s what_disk
sys_disk move.w ID_buffer+$a,d7
what_disk move.b d7,disks_in(a2,d6.w)
move.b #$ff,track_in(a2)
movem.l (a7)+,a6/d0-d1/d4-d7
rts
stepcheck moveq #0,d7
move.b use_drive(a2),d7
btst #1,tracksides(a2,d7.w)
bne.s h_odd
bsr stepin
bra.s stepdone
h_odd bsr stepout
stepdone rts
wait1msec moveq #1,d7
cia_wait move.b #$08,$f00(a1) ;set one shot / stop timer.
move.b #$cc,$600(a1) ;set timer lo
move.b #$02,$700(a1) ;set timer hi (starts counter)
ciawlp2 btst #0,$f00(a1) ;wait for ciab timer b to timeout
bne.s ciawlp2
subq.w #1,d7
bne.s cia_wait ;d7 = milliseconds to wait.
rts
*******************************************************************************
Attempts equ $0
Error equ $2
Start_motor equ $3
Disks_in equ $4
Tracksides equ $8
Track_in equ $c
Drives_avail equ $d
Use_drive equ $e
variables dcb.l 4,$0
ID_buffer dcb.l 3,$0
section chipstuff,data_c
MFMbuffer dcb.w $1910,$0000
*******************************************************************************